package cn.itcast.web.controller.cargo;

import cn.itcast.domain.cargo.*;
import cn.itcast.domain.system.User;
import cn.itcast.service.cargo.ContractService;
import cn.itcast.service.cargo.ExportProductService;
import cn.itcast.service.cargo.ExportService;
import cn.itcast.vo.ExportProductVo;
import cn.itcast.vo.ExportResult;
import cn.itcast.vo.ExportVo;
import cn.itcast.web.controller.BaseController;
import cn.itcast.web.utils.BeanMapUtils;
import com.alibaba.dubbo.config.annotation.Reference;
import com.github.pagehelper.PageInfo;
import net.sf.jasperreports.engine.*;
import net.sf.jasperreports.engine.data.JRBeanCollectionDataSource;
import org.apache.cxf.jaxrs.client.WebClient;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Controller;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author LT
 * @version 1.0.0
 * @ClassName ExportController.java
 * @Description TODO 合同管理视图层
 * @createTime 2020年04月05日 18:34:00
 */
@Controller                        // 控制层
@RequestMapping("/cargo/export")   // 请求映射
public class ExportController extends BaseController {

    @Reference
    private ContractService contractService;

    @Reference
    private ExportService exportService;

    @Reference
    private ExportProductService exportProductService;

    /*
       作用： 显示状态为1的购销合同
       url :  /cargo/export/contractList.do
       参数： 无
       返回值： 返回合同管理页面 cargo/export/export-contractList
    */
    @RequestMapping("/contractList")
    public String contractList(@RequestParam(defaultValue = "1") int pageNum,
                               @RequestParam(defaultValue = "10") int pageSize) {
        ContractExample contractExample = new ContractExample();
        contractExample.setOrderByClause("create_time desc");
        contractExample.createCriteria().andCompanyIdEqualTo(getLoginCompanyId()).andStateEqualTo(1);

        PageInfo<Contract> pageInfo = contractService.findByPage(contractExample, pageNum, pageSize);
        request.setAttribute("pageInfo", pageInfo);
        return "cargo/export/export-contractList";
    }

    /**
     * 作用： 显示的所有报运单
     *
     * @param pageNum
     * @param pageSize
     * @return "cargo/export/export-list";
     */
    @RequestMapping("/list")
    public String list(@RequestParam(defaultValue = "1") int pageNum,
                       @RequestParam(defaultValue = "10") int pageSize) {
        ExportExample exportExample = new ExportExample();
        exportExample.setOrderByClause("create_time desc");
        exportExample.createCriteria().andCompanyIdEqualTo(getLoginCompanyId());
        PageInfo<Export> pageInfo = exportService.findByPage(exportExample, pageNum, pageSize);
        request.setAttribute("pageInfo", pageInfo);
        return "cargo/export/export-list";
    }

    /**
     * 合同管理：点击报运
     *
     * @param id
     * @return
     */
    @RequestMapping("/toExport")
    public String toExport(String id) {
        request.setAttribute("id", id);
        return "cargo/export/export-toExport";
    }

    /**
     * 保存修改报运单
     *
     * @param export
     * @return "redirect:/cargo/export/list.do"
     */
    @RequestMapping("edit")
    public String edit(Export export) {
        // 购销合同的所属公司的id
        export.setCompanyId(getLoginCompanyId());
        // 购销合同的所属公司的名字
        export.setCompanyName(getLoginCompanyName());
        // 购销合同创建人
        export.setCreateBy(getLoginUser().getId());
        // 购销合同创建人所属的部门
        export.setCreateDept(getLoginUser().getDeptId());

        if (StringUtils.isEmpty(export.getId())) {
            // 保存
            exportService.save(export);
        } else {
            // 更新
            exportService.update(export);
        }
        return "redirect:/cargo/export/list.do";
    }


    /*
 作用: 进入修改报运单的页面
 url ： cargo/export/toUpdate.do
 参数： id  报运单的id
 返回： 修改报运单页面
  */
    @RequestMapping("toUpdate")
    public String toUpdate(String id) {
        //1. 查找出报运单
        Export export = exportService.findById(id);
        request.setAttribute("export", export);

        //2. 查找出报运单下面的所有商品
        ExportProductExample exportProductExample = new ExportProductExample();
        exportProductExample.createCriteria().andExportIdEqualTo(id);
        List<ExportProduct> exportProductList = exportProductService.findAll(exportProductExample);
        request.setAttribute("eps", exportProductList);
        return "cargo/export/export-update";
    }

    /**
     * 根据报运单id查看报运单
     * url ： /cargo/export/toView.do?id=804d7e6c-4eeb-4826-9a8c-8c389fe7a786
     *
     * @param id
     * @return
     */
    @RequestMapping("toView")
    public String toView(String id) {
        Export export = exportService.findById(id);
        request.setAttribute("export", export);
        return "cargo/export/export-view";
    }

    /**
     * 提交报运单
     * url ： /cargo/export/submit.do?id=804d7e6c-4eeb-4826-9a8c-8c389fe7a786
     *
     * @param id
     * @return
     */
    @RequestMapping("submit")
    public String submit(String id) {
        Export export = exportService.findById(id);
        export.setState(1);
        exportService.update(export);
        return "redirect:/cargo/export/list.do";
    }

    /**
     * 提交报运单
     * url ： /cargo/export/submit.do?id=804d7e6c-4eeb-4826-9a8c-8c389fe7a786
     *
     * @param id
     * @return
     */
    @RequestMapping("cancel")
    public String cancel(String id) {
        Export export = exportService.findById(id);
        export.setState(0);
        exportService.update(export);
        return "redirect:/cargo/export/list.do";
    }

    /**
     * 电子报运
     * url ： /cargo/export/exportE.do?id=804d7e6c-4eeb-4826-9a8c-8c389fe7a786
     *
     * @param id
     * @return
     */
    @RequestMapping("exportE")
    public String exportE(String id) {
        // 1.根据报运单的id找到报运单
        Export export = exportService.findById(id);
        // 2.把报运单的信息拷贝到ExportVo对象中, 其中这里有一个大坑：要求ExportVo的id必须exportId要一直。
        ExportVo exportVo = new ExportVo();
        BeanUtils.copyProperties(export, exportVo);
        // 所属报运单
        exportVo.setExportId(export.getId());

        // 3.根据报运单id查找到所有的报运商品
        ExportProductExample exportProductExample = new ExportProductExample();
        exportProductExample.createCriteria().andExportIdEqualTo(id);
        List<ExportProduct> exportProductList = exportProductService.findAll(exportProductExample);

        //4. 遍历报运商品然后把商品的信息封装到ExportProductVo对象中，然后添加到ExportVo对象的products 属性中
        for (ExportProduct exportProduct : exportProductList) {
            ExportProductVo exportProductVo = new ExportProductVo();
            // 拷贝属性数据
            BeanUtils.copyProperties(exportProduct, exportProductVo);
            // 所属的报运单
            exportProductVo.setExportId(export.getId());
            // 所属报运商品的id
            exportProductVo.setExportProductId(exportProduct.getId());
            // 把exportProductVo对象添加到ExportVo对象中
            exportVo.getProducts().add(exportProductVo);
        }
        // 5. 把ExportVo对象交给海关平台去审核(调用webservice)
        WebClient.create("http://localhost:9090/ws/export/user").post(exportVo);

        // 6. 调用海关平台的webservice接口，去好看当前报运单的审核的结果
        ExportResult exportResult = WebClient.create("http://localhost:9090/ws/export/user/" + id).get(ExportResult.class);
        //7. 把审核的结果信息更新到本地的报运单表中
        exportService.updateByResult(exportResult);
        return "redirect:/cargo/export/list.do";
    }

    /**
     * pdf报运单
     * url ： /cargo/export/exportPdf.do?id=4028d3cf567275410156735276210001
     * 参数： id  报运单的id
     * 返回： 无返回，因为最后要是要下载
     *
     * @param id
     * @throws Exception
     */
    @RequestMapping("exportPdf")
    @ResponseBody
    public void exportPdf(String id) throws Exception {
        // 1.读取到jasper的文件输入流
        InputStream inputStream = session.getServletContext().getResourceAsStream("/jasper/export.jasper");
        //2. 使用jasper文件输入流与数据结合，形参一个jasperPrint对象
        /*  fillReport() , 把数据和jasperPrint对象结合形参一个jasperPrint对象
                参数一： japser文件的输入流
                参数二： 填充参数， 这里的参数是不需要遍历
                参数三： 需要遍历数据
         */
        // test03
        // Map<String, Object> map = new HashMap<>();
        // map.putIfAbsent("username", "大傻");
        // map.put("email", "840164190@itcast.cn");
        // map.put("company", "拉胯黑马");
        // map.put("deptName", "家里蹲部");
        // 模拟从数据库中查找到的数据 test04
        // List<User> list = new ArrayList<>();
        // for (int i = 0; i < 5; i++) {
        //     User user = new User();
        //     user.setUserName("大傻" + i);
        //     user.setEmail("840164190@qq.com");
        //     user.setCompanyName("虎牙直播");
        //     user.setDeptName("网管");
        //     list.add(user);
        // }

        // 2.1 找到报运单
        Export export = exportService.findById(id);
        // 2.2 把报运单的对象转换为map spring 提供了一个工具把对象转换为Map
        Map<String, Object> map = BeanMapUtils.beanToMap(export);
        // 2.3 找到报运单下的商品
        ExportProductExample exportProductExample = new ExportProductExample();
        exportProductExample.createCriteria().andExportIdEqualTo(id);
        List<ExportProduct> list = exportProductService.findAll(exportProductExample);

        // 把list集合数据交给模板(jasperPrint管理器)
        // JasperPrint jasperPrint = JasperFillManager.fillReport(inputStream, map, new JREmptyDataSource());
        JasperPrint jasperPrint = JasperFillManager.fillReport(inputStream, map, new JRBeanCollectionDataSource(list));

        // 通知浏览器以附件形式处理数据的内容即可
        response.setHeader("content-disposition", "attachement;filename=export.pdf");

        // 3.把jasperPrint对象输出，产生一个pdf文件
        JasperExportManager.exportReportToPdfStream(jasperPrint, response.getOutputStream());
    }
}

